import {defineStore} from 'pinia'
import { IProduct, buyProducts } from '../api/shop'
import { useProductsStore } from './products'

// &  合并
// Omit 干掉其中的一个数据类型
// 这个剩余的就是  { id, title, price, quantity }
type CartProduct = {
  quantity:number
} & Omit<IProduct,'inventory'>

export const useCartStore = defineStore('cart',{
  state:()=>{
    return {
      cartProducts:[] as CartProduct[] , //已加入购物车商品列表
      checkoutStatus:null as null | string
    }
  },


  // reduce   JSCORE04
  // 参数2: 是total的默认初始值, 如果不写,则默认为数组的第一个元素
  getters:{
    totalPrice (state){
      return state.cartProducts.reduce(((total,item)=>{
        return total = total + item.price * item.quantity
      }),0)
    }
  },

  actions:{
    addProducToCart(product:IProduct){
      console.log('addProducToCart',product);
      
      // 看看商品还有没有库存
      if(product.inventory < 1){
        alert('该商品无库存')
        return
      }
      // 检查购物车中是否已经有该商品
      // find()方法用于查找数组中符合条件的第一个元素，如果没有符合条件的元素，则返回undefined
      // 更改find()返回的值，原数组也会被改变
      // 请记住，传播一个对象是一个浅拷贝，这意味着如果你有一个嵌套的对象，那么它不会被复制，而是被引用
      const cartItem = this.cartProducts.find(item=>item.id == product.id)
      // 如果有则数量 + 1
      if(cartItem){
        cartItem.quantity++
      }else{
        // 如果没有则添加到购物车列表项中
        // 这里product,还是原来的对象类型{ id, title, price, inventory }
        // 现在的cartProducts,数组中的对象push的类型是{ id, title, price, quantity }
        // 所以不能直接push添加
        this.cartProducts.push({ 
          id:product.id,
          title:product.title,
          price:product.price,
          quantity :1
        })
      }
      // 更新库存
      const ProductsStore = useProductsStore()
      ProductsStore.decrementProduct(product)
    },

    async checkout () {
      const ret = await buyProducts()
      this.checkoutStatus = ret ? '成功' : '失败'
      if(ret){
        this.cartProducts = []
      }
    }
  }
})